package com.thunder.kocho.circle;

import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.BlurMaskFilter;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.SweepGradient;
import android.util.AttributeSet;
import android.view.View;
import androidx.annotation.NonNull;

import com.thunder.kocho.R;

import java.util.Timer;
import java.util.TimerTask;

import static java.lang.Math.cos;
import static java.lang.Math.sin;

public class CircleCPView extends BaseCircleView{

    private int mCPCycle;
    private float mStrokeWidth;

    private Paint mOuterPaint1;
    private Paint mOuterPaint2;
    private Paint mShinePaint1;
    private Paint mShinePaint2;

    private ObjectAnimator mAnimator;
    private float mBlurRadius;
    private float mOuterRotate;
    private float cx1;
    private float cy1;
    private float cx2;
    private float cy2;

    private boolean isOuterRingHid=false;

    private final int[] colors1={Color.BLUE,Color.RED,Color.BLUE};
    private final float[] positions={0,0.425f,1};

    public CircleCPView(Context context){
        this(context,null);
    }

    public CircleCPView(Context context, AttributeSet attrs){
        this(context,attrs,0);
    }

    public CircleCPView(Context context,AttributeSet attrs,int defStyle){
        super(context,attrs,defStyle);
    }

    @Override
    protected void initSubAttr(Context context, AttributeSet attrs,int defStyle) {
        TypedArray typedArray=context.obtainStyledAttributes(attrs, R.styleable.CircleCPView,defStyle,0);
        mCPCycle=typedArray.getInt(R.styleable.CircleCPView_cpCycle,2000);
        mStrokeWidth=typedArray.getFloat(R.styleable.CircleCPView_cpStrokeWidth,9);
        typedArray.recycle();
        mBlurRadius =2*mStrokeWidth;
    }

    @Override
    protected void init() {
        super.init();
        mOuterPaint1=new Paint(Paint.ANTI_ALIAS_FLAG);
        mOuterPaint1.setStyle(Paint.Style.STROKE);
        mOuterPaint1.setStrokeWidth(mStrokeWidth);

        mShinePaint1=new Paint(Paint.ANTI_ALIAS_FLAG);
        mShinePaint1.setStyle(Paint.Style.FILL);
        mShinePaint1.setMaskFilter(new BlurMaskFilter(mStrokeWidth, BlurMaskFilter.Blur.NORMAL));
        mShinePaint1.setColor(Color.BLUE);

        mOuterPaint2=new Paint(Paint.ANTI_ALIAS_FLAG);
        mOuterPaint2.setStyle(Paint.Style.STROKE);
        mOuterPaint2.setStrokeWidth(mStrokeWidth);

        mShinePaint2=new Paint(Paint.ANTI_ALIAS_FLAG);
        mShinePaint2.setStyle(Paint.Style.FILL);
        mShinePaint2.setMaskFilter(new BlurMaskFilter(mStrokeWidth, BlurMaskFilter.Blur.NORMAL));
        mShinePaint2.setColor(Color.RED);

        PropertyValuesHolder holder=PropertyValuesHolder.ofFloat("Whole",0,1);
        PropertyValuesHolder holder2=PropertyValuesHolder.ofFloat("ShineRotate",0,(float)(2*Math.PI));
        mAnimator=ObjectAnimator.ofPropertyValuesHolder(this,holder,holder2);
        mAnimator.setDuration(mCPCycle);
        mAnimator.setRepeatCount(ValueAnimator.INFINITE);
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        SweepGradient sweepGradient1=new SweepGradient(w/2f,h/2f,colors1,positions);
        mOuterPaint1.setShader(sweepGradient1);
        SweepGradient sweepGradient2=new SweepGradient(w/2f,h/2f,colors1,positions);
        mOuterPaint2.setShader(sweepGradient2);
        cx1=mOuterRingRect.right;
        cy1=mOuterRingRect.centerY();
        cx2=mOuterRingRect.left;
        cy2=mOuterRingRect.centerY();
    }

    @Override
    protected Rect obtainCircleRect(Rect rect) {
        int cx=rect.centerX();
        int cy=rect.centerY();
        int side=(int)(rect.width()*0.4f);
        return new Rect(cx-side,cy-side,cx+side,cy+side);
    }

    @Override
    protected Rect obtainOuterRingRect(Rect rect) {
        int cx=rect.centerX();
        int cy=rect.centerY();
        setPivotX(cx);
        setPivotY(cy);
        int side= (int) (rect.width()/2f+mStrokeWidth);
        return new Rect(cx-side,cy-side,cx+side,cy+side);
    }

    @Override
    protected void drawOuterRing(Canvas canvas) {
        if(!isOuterRingHid){
            canvas.drawArc((float)mOuterRingRect.left,(float)mOuterRingRect.top,(float)mOuterRingRect.right,(float)mOuterRingRect.bottom,mOuterRotate,165,false,mOuterPaint1);
            canvas.drawArc((float)mOuterRingRect.left,(float)mOuterRingRect.top,(float)mOuterRingRect.right,(float)mOuterRingRect.bottom,180+mOuterRotate,165,false,mOuterPaint2);
            canvas.drawCircle(cx1,cy1,mBlurRadius,mShinePaint1);
            canvas.drawCircle(cx2,cy2, mBlurRadius,mShinePaint2);
        }
    }

    private void setWhole(float fraction){
        mOuterRotate=360*fraction;
        mBlurRadius =mStrokeWidth*3f*(1-0.95f*Math.abs(0.5f-fraction));
        if(fraction<=575){
            positions[0]=fraction;
            positions[1]= (float) (0.425+fraction);
        }else{
            positions[0]=fraction-0.575f;
            positions[1]=fraction-0.15f;
        }

        //Log.d(TAG,"sin= "+sin(mOuterRotate)+"  cos="+cos(mOuterRotate));

        invalidate();
    }

    private void setShineRotate(float rotate){
        float r=mOuterRingRect.width()/2f;
        cx1= (float) (mOuterRingRect.right+r*(cos(rotate)-1));
        cy1= (float) (mOuterRingRect.centerY()+r*sin(rotate));
        cx2=(float)(mOuterRingRect.left+r*(1-cos(rotate)));
        cy2=(float)(mOuterRingRect.centerY()-r*sin(rotate));
        invalidate();
    }

    /**
     * 延迟开启动画
     * @param delay 延迟的毫秒数
     */
    public void postDelayAnimation(int delay) {
        Timer timer = new Timer();
        TimerTask task = new TimerTask() {
            @Override
            public void run() {
                if (mAnimator != null) {
                    if (!mAnimator.isStarted()) {
                        post(() -> {
                            setVisibility(VISIBLE);
                            mAnimator.start();
                        });
                    }
                }
            }
        };
        timer.schedule(task, delay);
    }

    /**
     * 隐藏或显示外围动画
     * @param isOuterRingHid true表示隐藏
     */
    public void setOuterRingHid(boolean isOuterRingHid){
        this.isOuterRingHid=isOuterRingHid;
        invalidate();
    }

    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        switch(visibility){
            case INVISIBLE:case GONE:
                if(mAnimator.isStarted()){
                    mAnimator.end();
                }
                break;

            case VISIBLE:
                break;
        }
    }



}
